package me.zhengjie.modules.weixin.processor;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import me.zhengjie.config.constant.WeChatConstant;
import me.zhengjie.config.exception.WeChatException;
import me.zhengjie.modules.weixin.dto.WeChatAccount;
import me.zhengjie.modules.weixin.message.AnalyzerReplyMessage;
import me.zhengjie.modules.weixin.message.custom.CustomTransInfoMessage;
import me.zhengjie.modules.weixin.message.reply.*;
import me.zhengjie.modules.weixin.utils.MD5Util;
import org.apache.commons.lang3.StringUtils;
import org.springframework.util.CollectionUtils;

import java.util.List;
import java.util.Map;

/**
 * 应用于当此模块设置过回复规则列表，用户发送关键字后，触发到模块中向用户回复信息的功能
 */
public abstract class AbstractProcessor {

    protected WeChatAccount account;

    protected AnalyzerReplyMessage reply;

    private JSONObject session;

    /**
     * 抽象方法 - 各子类需实现 回复消息功能
     *
     * @return
     * @throws Exception
     */
    public abstract AbstractReplyMessage process() throws Exception;

    /**
     * 开放get方法
     *
     * @return
     */
    public JSONObject getSession() {
        return session;
    }

    protected boolean beginContext(int expire) {
        if (this.reply.isInContext()) {
            return true;
        }

        Map<String, Object> receiveMsg = reply.getReceiveMsg();
        String sessionId = MD5Util.md5("WeSession:" + account.getAppId() + receiveMsg.get("FromUserName") + receiveMsg.get("ToUserName"));

        this.session = new JSONObject();
        this.session.put("__sessionid", sessionId);
        this.session.put("__appid", account.getAppId());
        this.session.put("__openid", receiveMsg.get("FromUserName"));
        this.session.put("__contextmodule", reply.getModule());
        this.session.put("__contextrule", reply.getRule());
        this.session.put("__contextexpire", System.currentTimeMillis() / 1000 + expire);
        this.session.put("__contextpriority", reply.getPriority());

        //CacheUtils.setObjectToCache(sessionId, this.session, expire);

        this.reply.setInContext(true);

        return true;
    }

    protected void endContext() {
        if (null == session || !session.containsKey("__sessionid")) {
            return;
        }
        this.session.remove("__contextmodule");
        this.session.remove("__contextrule");
        this.session.remove("__contextexpire");
        this.session.remove("__contextpriority");

        this.session = null;

        this.reply.setInContext(false);
    }

    protected boolean refreshContext(int expire) {
        if (!this.reply.isInContext()) {
            return false;
        }
        if (null == this.session || !this.session.containsKey("__sessionid")) {
            beginContext(expire);
        }
        this.session.put("__contextexpire", System.currentTimeMillis() / 1000 + expire);

        return true;
    }

    protected String textRespond() {

        if (null != reply.getReplyMsg() && null != reply.getReplyMsg().getMsgBody()) {

            ReplyTextMessage msg = JSON.parseObject(JSON.toJSONString(reply.getReplyMsg().getMsgBody()), ReplyTextMessage.class);
            return msg.getContent();
        }
        return "";
    }

    protected String imageRespond() {

        if (null != reply.getReplyMsg() && null != reply.getReplyMsg().getMsgBody()) {
            ReplyImageMessage msg = JSON.parseObject(JSON.toJSONString(reply.getReplyMsg().getMsgBody()), ReplyImageMessage.class);
            return msg.getImage().getMediaId();
        }
        return "";
    }

    protected Map<String, Object> musicRespond() {
        return null;
    }

    protected List<Map<String, Object>> newsRespond(boolean queryMaterial) {
        return null;
    }

    protected String voiceRespond() {
        return null;
    }

    protected Map<String, Object> videoRespond() {
        return null;
    }

    protected AbstractReplyMessage respText(String content) {

        if (StringUtils.isBlank(content)) {
//            throw new WeChatException(WeChatConstant.SUCCESS_FLAG);
            return null;
        }

        Map<String, Object> receiveMsg = reply.getReceiveMsg();
        ReplyTextMessage replyMsg = new ReplyTextMessage(content);
        replyMsg.setFromUserName((String) receiveMsg.get("ToUserName"));
        replyMsg.setToUserName((String) receiveMsg.get("FromUserName"));

        return replyMsg;
    }

    protected AbstractReplyMessage respImage(String mediaId) {

        if (StringUtils.isBlank(mediaId)) {
            throw new WeChatException(WeChatConstant.SUCCESS_FLAG);
        }

        Map<String, Object> receiveMsg = reply.getReceiveMsg();

        ReplyImageMessage replyMsg = new ReplyImageMessage(mediaId);
        replyMsg.setFromUserName((String) receiveMsg.get("ToUserName"));
        replyMsg.setToUserName((String) receiveMsg.get("FromUserName"));

        return replyMsg;
    }

    protected AbstractReplyMessage respVoice(String mediaId) {

        if (StringUtils.isBlank(mediaId)) {
            throw new WeChatException(WeChatConstant.SUCCESS_FLAG);
        }

        Map<String, Object> receiveMsg = reply.getReceiveMsg();

        ReplyVoiceMessage replyMsg = new ReplyVoiceMessage(mediaId);
        replyMsg.setFromUserName((String) receiveMsg.get("ToUserName"));
        replyMsg.setToUserName((String) receiveMsg.get("FromUserName"));

        return replyMsg;
    }

    protected AbstractReplyMessage respVideo(Map<String, Object> video) {
        String mediaId = (String) video.get("mediaid");
        String title = (String) video.get("title");
        String description = (String) video.get("description");
        if (StringUtils.isBlank(mediaId)) {
            throw new WeChatException(WeChatConstant.SUCCESS_FLAG);
        }

        Map<String, Object> receiveMsg = reply.getReceiveMsg();

        ReplyVideoMessage replyMsg = new ReplyVideoMessage(mediaId, title, description);
        replyMsg.setFromUserName((String) receiveMsg.get("ToUserName"));
        replyMsg.setToUserName((String) receiveMsg.get("FromUserName"));

        return replyMsg;
    }

    protected AbstractReplyMessage respMusic(Map<String, Object> music) {
        String title = (String) music.get("title");
        String description = (String) music.get("description");
        String musicUrl = (String) music.get("url");
        String hQMusicUrl = (String) music.get("hqurl");
        String thumbMediaId = (String) music.get("thumbMediaId");
        if (StringUtils.isBlank(musicUrl)) {
            throw new WeChatException(WeChatConstant.SUCCESS_FLAG);
        }

        Map<String, Object> receiveMsg = reply.getReceiveMsg();
        ReplyMusicMessage replyMsg = new ReplyMusicMessage(title, description, musicUrl, hQMusicUrl, thumbMediaId);
        replyMsg.setFromUserName((String) receiveMsg.get("ToUserName"));
        replyMsg.setToUserName((String) receiveMsg.get("FromUserName"));

        return replyMsg;
    }

    protected AbstractReplyMessage respNews(List<Map<String, Object>> news) {

        if (CollectionUtils.isEmpty(news)) {
            throw new WeChatException(WeChatConstant.SUCCESS_FLAG);
        }

        Map<String, Object> receiveMsg = reply.getReceiveMsg();

        ReplyNewsMessage replyMsg = new ReplyNewsMessage();

        for (Map<String, Object> msg : news) {
            ReplyNewsMessage.NewsMessage newsMsg = new ReplyNewsMessage.NewsMessage();
            newsMsg.setTitle((String) msg.get("title"));
            newsMsg.setDescription((String) msg.get("description"));
            newsMsg.setPicUrl((String) msg.get("thumb"));
            newsMsg.setUrl((String) msg.get("url"));

            replyMsg.getArticles().add(newsMsg);
        }
        replyMsg.setArticleCount(replyMsg.getArticles().size());
        replyMsg.setFromUserName((String) receiveMsg.get("ToUserName"));
        replyMsg.setToUserName((String) receiveMsg.get("FromUserName"));

        return replyMsg;
    }

    protected AbstractReplyMessage respCustom(String kfAccount) {

        Map<String, Object> receiveMsg = reply.getReceiveMsg();

        CustomTransInfoMessage replyMsg = new CustomTransInfoMessage(kfAccount);
        replyMsg.setFromUserName((String) receiveMsg.get("ToUserName"));
        replyMsg.setToUserName((String) receiveMsg.get("FromUserName"));

        return replyMsg;
    }

}
